﻿namespace Resharper.Abstractions.CodeDom.Types.Classes
{
  using System.Collections.Generic;
  using System.Linq;
  using JetBrains.Annotations;
  using JetBrains.ReSharper.Psi.CSharp.Tree;
  using Resharper.Abstractions.CodeDom.TypeMembers.Fields.Constants;
  using Resharper.Abstractions.CodeDom.TypeMembers.Methods;
  using Resharper.Abstractions.CodeDom.TypeMembers.Properties;
  using Resharper.Abstractions.Solutions;

  /// <summary>Defines the <see cref="Class"/> class.</summary>
  public class Class : TypeElement
  {
    #region Constructors and Destructors

    /// <summary>Initializes a new instance of the <see cref="Class"/> class.</summary>
    /// <param name="class">The class element.</param>
    internal Class([NotNull] IClassDeclaration @class) : base(@class)
    {
    }

    #endregion

    #region Properties

    /// <summary>
    /// Gets the constants.
    /// </summary>
    [NotNull]
    public IEnumerable<Constant> Constants
    {
      get
      {
        var fields = this.InternalClass.ConstantDeclarations;

        return fields.Select(c => new Constant(c));
      }
    }

    /// <summary>
    /// Gets the functions.
    /// </summary>
    [NotNull]
    public IEnumerable<Method> Functions
    {
      get
      {
        var fields = this.InternalClass.MethodDeclarations;

        return fields.Select(c => new Method(c));
      }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this instance is abstract.
    /// </summary>
    /// <value><c>true</c> if this instance is abstract; otherwise, <c>false</c>.</value>
    public bool IsAbstract
    {
      get
      {
        return this.InternalClass.IsAbstract;
      }

      set
      {
        this.InternalClass.SetAbstract(value);
      }
    }

    /// <summary>
    /// Gets the language.
    /// </summary>
    [NotNull]
    public Language Language
    {
      get
      {
        return new Language(this.InternalClass.Language);
      }
    }

    /// <summary>
    /// Gets the properties.
    /// </summary>
    [NotNull]
    public IEnumerable<Property> Properties
    {
      get
      {
        var fields = this.InternalClass.PropertyDeclarations;

        return fields.Select(c => new Property(c));
      }
    }

    /// <summary>The class element field.</summary>
    [NotNull]
    internal IClassDeclaration InternalClass
    {
      get
      {
        return (IClassDeclaration)this.InternalTreeNode;
      }
    }

    #endregion
  }
}